package org.maylove.wuziqi.game;

import org.maylove.wuziqi.pojo.game.dto.GameRoomDto;
import org.maylove.wuziqi.pojo.game.dto.GameRoomPlayerDto;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;

import java.util.Objects;

public class GameManager {

    //  设置房间数量
    private static final Integer ROOM_NUMBER = 500;

    private static GameManager instance;
    private GameNumTree gameNumTree;
    private GameRoom[] gameRooms;

    public GameManager(ApplicationEventPublisher publisher) {
        gameNumTree = new GameNumTree(ROOM_NUMBER);
        gameRooms = new GameRoom[ROOM_NUMBER + 1];
        for(int i = 1; i <= ROOM_NUMBER ;i++) gameRooms[i] = new GameRoom(publisher);
    }

    public static GameManager getInstance(ApplicationEventPublisher publisher) {
        if (instance == null) {
            instance = new GameManager(publisher);
        }
        return instance;
    }

    public synchronized Integer getRoom(Long playerId) {
        int res = gameNumTree.getRoom();
        if(res == -1) return -1;
        gameRooms[res].setRoomId(res);
        gameRooms[res].initRoom();
        gameRooms[res].setPlayer1(playerId);
        return res;
    }

    public synchronized Integer joinRoom(Long playerId, int roomId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return -1;

        //  判断房间是否已满
        if(gameRooms[roomId].getPlayer2() != null) return -2;

        //  判断是否自己加入自己的房间
        if(Objects.equals(gameRooms[roomId].getPlayer1(), playerId)) return -3;

        
        gameRooms[roomId].setPlayer2(playerId);
        return 0;
    }

    public String prepare(Integer roomId, Long userId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        if(Objects.equals(gameRooms[roomId].getPlayer1(), userId)) {
            return gameRooms[roomId].prepare(1);
        }
        if(gameRooms[roomId].getPlayer2() != null && Objects.equals(gameRooms[roomId].getPlayer2(), userId)) {
            return gameRooms[roomId].prepare(2);
        }
        return "The player does not exist in the room!";
    }

    public GameRoomDto get(Long userId, Integer roomId) {
        //  判权
        if(roomId > ROOM_NUMBER || !userId.equals(gameRooms[roomId].getPlayer1()) && !userId.equals(gameRooms[roomId].getPlayer2())) return null;

        //  判断房间是否创建
        if(gameRooms[roomId].getPlayer1() == null) return null;

        GameRoomDto dto = new GameRoomDto();
        BeanUtils.copyProperties(gameRooms[roomId], dto);
        return dto;
    }

    public String game(Long userId, Integer roomId, Integer x, Integer y) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        //  判断房间是否已经开始游戏
        if(!gameRooms[roomId].getWaitPlay1() || !gameRooms[roomId].getWaitPlay2()) return "The room has not started the game yet!";

        //  判权
        if(!userId.equals(gameRooms[roomId].getPlayer1()) && !userId.equals(gameRooms[roomId].getPlayer2())) return "The player does not belong to the room!";

        if(userId.equals(gameRooms[roomId].getPlayer1())) return gameRooms[roomId].game(1, x, y);
        else return gameRooms[roomId].game(2, x, y);
    }

    public GameRoomPlayerDto get(Integer roomId) {
        if(roomId > ROOM_NUMBER) return null;
        GameRoomPlayerDto dto = new GameRoomPlayerDto();
        BeanUtils.copyProperties(gameRooms[roomId], dto);
        return dto;
    }

    public String back(Long userId, Integer roomId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        //  判断房间是否已经开始游戏
        if(!gameRooms[roomId].getWaitPlay1() || !gameRooms[roomId].getWaitPlay2()) return "The room has not started the game yet!";

        //  判权
        if(!userId.equals(gameRooms[roomId].getPlayer1()) && !userId.equals(gameRooms[roomId].getPlayer2())) return "The player does not belong to the room!";

        if(userId.equals(gameRooms[roomId].getPlayer1())) return gameRooms[roomId].back(1);
        else return gameRooms[roomId].back(2);
    }

    public String giveUp(Long userId, Integer roomId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        //  判断房间是否已经开始游戏
        if(!gameRooms[roomId].getWaitPlay1() || !gameRooms[roomId].getWaitPlay2()) return "The room has not started the game yet!";

        //  判权
        if(!userId.equals(gameRooms[roomId].getPlayer1()) && !userId.equals(gameRooms[roomId].getPlayer2())) return "The player does not belong to the room!";

        if(userId.equals(gameRooms[roomId].getPlayer1())) return gameRooms[roomId].giveUp(1);
        else return gameRooms[roomId].giveUp(2);
    }

    public void cleanRoom(Integer roomId) {
        gameRooms[roomId].initRoom();
    }

    public void free(int roomId) {
        gameRooms[roomId].free();
        gameRooms[roomId].setPlayer1(null);
        gameRooms[roomId].setPlayer2(null);
        gameNumTree.putRoom(roomId);
    }

    public String exit(Long userId, Integer roomId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        //  判权
        if(!userId.equals(gameRooms[roomId].getPlayer1()) && !userId.equals(gameRooms[roomId].getPlayer2())) {
            return "The player does not belong to the room!";
        }

        //  判断是否开始游戏
        if(gameRooms[roomId].getWaitPlay1() && gameRooms[roomId].getWaitPlay2()) return "The game has already started!";

        if(userId.equals(gameRooms[roomId].getPlayer1())) return "success1";
        else return "success2";
    }

    public String trans(Long userId, Integer roomId) {
        //  判断房间是否创建
        if(roomId > ROOM_NUMBER || gameRooms[roomId].getPlayer1() == null) return "Room not created!";

        //  判断是否开始游戏
        if(gameRooms[roomId].getWaitPlay1() && gameRooms[roomId].getWaitPlay2()) return "The game has already started!";

        //  判断是否存在玩家二
        if(gameRooms[roomId].getPlayer2() == null) return "There is no player 2 in the room!";

        //  判权
        if(!userId.equals(gameRooms[roomId].getPlayer1())) return "No authority to transfer to the homeowner!";

        Long tmp = gameRooms[roomId].getPlayer2();
        gameRooms[roomId].setPlayer2(gameRooms[roomId].getPlayer1());
        gameRooms[roomId].setPlayer1(tmp);
        gameRooms[roomId].setWaitPlay1(false);
        gameRooms[roomId].setWaitPlay2(false);
        return "success";
    }

    public Integer[][] getBoard(Integer roomId) {
        if(roomId > ROOM_NUMBER) return null;
        return gameRooms[roomId].getBoard();
    }
}
